/* ===================

AX2E (AXESCON XACML 2.0 Engine) is the Java authorization engine, which implements OASIS XACML 2.0 standard.
Copyright (C) 2007 AXESCON LLC

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA


Contact: AXESCON LLC - info{at}axescon.com

 =================== */
package axescon.xacml.engine.fn;

import axescon.xacml.api.*;
import axescon.xacml.model.ctx.XacmlCtx;
import axescon.xacml.model.policy.AttributeValue;
import axescon.xacml.model.policy.Expression;
import axescon.xacml.model.shared.attr.IntegerAttribute;
import axescon.xacml.model.shared.attr.StringAttribute;
import x0ContextSchemaOs.oasisNamesTcXacml2.RequestType;

/**
 * @author Date: Sep 28, 2005
 *         Responsibilities: see A.3.15 XPath-based functions
 */
public class FnXpathNodeCount extends AbstractFn {
    public int getArgTypeListLength() {
        return 1;
    }

    public Liquid exec(Liquid[] args) throws ExpressionEvalIndeterminateException {
        throw new ExpressionEvalIndeterminateException("FnXpathNodeCount.exec(AttributeValue[][] args) method shouldn't be ever called.");
    }

    public Liquid exec(Expression[] args, CtxHandler ch, XacmlCtx req, ExpressionEvaluator ee) throws
            XacmlException, ExpressionEvalIndeterminateException {
        assert ee != null: "Null expression evaluator passed into FnXpathNodeCount function.";

        Liquid[] avs = ee.eval(args, ch, req);
        AttributeValue xpathAttr = avs[0].getSingularUnsafe();
        if (!(xpathAttr instanceof StringAttribute))
            throw new ExpressionEvalIndeterminateException("FnXpathNodeCount# argument is not xpath string.");
        String xpath = xpathAttr.getStringValue();

        xpath = args[0].getRootPolicyObject().getNamespacesDecls() + xpath;


        try {
            RequestType rt = (RequestType) req.getLLObject();
            return new Liquid(new IntegerAttribute(rt.selectPath(xpath).length));
        } catch (Exception e) {
            throw new ExpressionEvalIndeterminateException("FnXpathNodeCount# can't evaluate xpath:" + xpath, e);
        }
    }
    public Class getReturnDataType() throws ExpressionEvalIndeterminateException {
        return IntegerAttribute.class;
    }

}
